﻿using GEPL.InterfaceLibrary;
using GEPL.StandardModulesLibrary.Properties;
using GEPL.StandardModulesLibrary.ViewModels.Common;
using GEPL.StandardModulesLibrary.Views.Common;
using System;
using System.Runtime.Serialization;

namespace GEPL.StandardModulesLibrary.Elements.Common
{
    [Serializable]
    public class LoopElement : IElement
    {
        private readonly LoopViewModel viewModel;

        public LoopElement()
        {
            viewModel = new LoopViewModel();
        }

        public LoopElement(SerializationInfo info, StreamingContext context)
        {
            viewModel = new LoopViewModel
            {
                IsEnd = info.GetBoolean(nameof(viewModel.IsEnd)),
                ForLoop = info.GetBoolean(nameof(viewModel.ForLoop)),
                WhileLoop = info.GetBoolean(nameof(viewModel.WhileLoop)),
                DoWhileLoop = info.GetBoolean(nameof(viewModel.DoWhileLoop)),
                RangeFrom = info.GetInt32(nameof(viewModel.RangeFrom)),
                RangeTo = info.GetInt32(nameof(viewModel.RangeTo)),
                Variable = info.GetString(nameof(viewModel.Variable)),
                WhileConditionValue1 = info.GetString(nameof(viewModel.WhileConditionValue1)),
                WhileConditionValue2 = info.GetString(nameof(viewModel.WhileConditionValue2)),
                SelectedWhileCondition = info.GetString(nameof(viewModel.SelectedWhileCondition))
            };
        }

        public ElementType ElementType
        {
            get { return viewModel.IsEnd ? ElementType.EndBlock : ElementType.StartBlock; }
        }

        public ProjectType ProjectType
        {
            get { return ProjectType.Any; }
        }

        public string ElementName
        {
            get { return Resources.Names_ForLoop; }
        }

        public object Data
        {
            get { return viewModel; }
        }

        public Type UserControlType
        {
            get { return typeof(LoopView); }
        }

        public string GetScript()
        {
            if (viewModel.ForLoop)
            {
                var @in = String.Format("range({0}, {1})", viewModel.RangeFrom, viewModel.RangeTo);
                return viewModel.IsEnd ? String.Empty : String.Format("for {0} in {1}:", viewModel.Variable, @in);
            }

            if (viewModel.WhileLoop)
            {
                return viewModel.IsEnd ?
                    String.Empty :
                    String.Format("while {0} {1} {2}:", viewModel.WhileConditionValue1, viewModel.SelectedWhileCondition, viewModel.WhileConditionValue2);
            }

            if (viewModel.DoWhileLoop)
            {
                return viewModel.IsEnd ?
                    String.Format("\tif not {0} {1} {2}:\n\t\tbreak", viewModel.WhileConditionValue1, viewModel.SelectedWhileCondition, viewModel.WhileConditionValue2) :
                    "while True:";
            }

            return String.Empty;
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue(nameof(viewModel.IsEnd), viewModel.IsEnd);
            info.AddValue(nameof(viewModel.ForLoop), viewModel.ForLoop);
            info.AddValue(nameof(viewModel.WhileLoop), viewModel.WhileLoop);
            info.AddValue(nameof(viewModel.DoWhileLoop), viewModel.DoWhileLoop);
            info.AddValue(nameof(viewModel.RangeFrom), viewModel.RangeFrom);
            info.AddValue(nameof(viewModel.RangeTo), viewModel.RangeTo);
            info.AddValue(nameof(viewModel.Variable), viewModel.Variable, typeof(String));
            info.AddValue(nameof(viewModel.WhileConditionValue1), viewModel.WhileConditionValue1);
            info.AddValue(nameof(viewModel.WhileConditionValue2), viewModel.WhileConditionValue2);
            info.AddValue(nameof(viewModel.SelectedWhileCondition), viewModel.SelectedWhileCondition);
        }
    }
}